from django.test import TestCase
from unittest import mock
from rest_framework.test import APIClient
from django.urls import reverse
from video.models import Videos
from user.models import UserProfile
from follow.models import Follow
import os
from bilimili_django import settings
from django.core.files.uploadedfile import SimpleUploadedFile
from play.models import Play
from video_reviewing.models import VideosReviewing
from video.views import increment_string
from video_reviewing.models import VideosReviewing
from column.models import Column
from favor.models import Favor


# Create your tests here.

class TestVideos(TestCase):
    def setUp(self):
        self.client = APIClient()
        self.user1 = UserProfile.objects.create_user(id=1, username='test1', password='test1234', is_active=True)
        self.user2 = UserProfile.objects.create_user(id=2, username='test2', password='test1234', is_active=True)
        self.user3 = UserProfile.objects.create_user(id=3, username='test3', password='test1234', is_active=True)
        self.video = Videos.objects.create(vid=1, duration=10, mup_id=2, type='sports', status=True)
        self.video_user3 = Videos.objects.create(vid=2, duration=10, mup_id=3, type='sports', status=False)
        # 未通过的视频（status = false）
        self.video_review_user3 = VideosReviewing.objects.create(vid=1, duration=10, mup_id=3, status=False,
                                                                 video_id=self.video_user3.vid)
        self.follow_1_2 = Follow.objects.create(fan_id=self.user1.id, mup_id=self.user2.id)
        self.follow_1_3 = Follow.objects.create(fan_id=self.user1.id, mup_id=self.user3.id)

        # 收藏专栏用
        self.user4 = UserProfile.objects.create_user(id=4, username='test4', password='test1234', is_active=True)
        self.user5 = UserProfile.objects.create_user(id=5, username='test5', password='test1234', is_active=True)
        self.column_user5 = Column.objects.create(coid=1, status=True, mup_id=5)
        self.column2_user5 = Column.objects.create(coid=2, status=True, mup_id=5)
        self.video_user5 = Videos.objects.create(vid=3, duration=10, mup_id=5, column_id=self.column_user5.coid,
                                                 status=True)
        self.favors = Favor.objects.create(fid=1, is_active=True, user_id_id=self.user4.id,
                                           video_id_id=self.video_user5.vid)

        self.test_filename = 'test_video'
        self.filename = 'test_video'
        self.test_path = os.path.join(settings.MEDIA_ROOT, 'videos/temp', self.test_filename)
        self.chunk_data = b'This is a test chunk'
        self.file = SimpleUploadedFile('test_chunk.mp4', self.chunk_data, content_type='video/mp4')
        # 定义保存路径
        self.temp_dir = os.path.join(settings.MEDIA_ROOT, 'videos/temp', self.filename)

        self.filetype = "mp4"
        self.title = "Test Video"
        self.tags = "tag1,tag2"
        self.video_type = "test_type"
        self.description = "Test video description"
        # 创建测试文件夹
        os.makedirs(self.test_path, exist_ok=True)

        os.makedirs(self.temp_dir, exist_ok=True)
        for i in range(3):  # 创建3个虚拟的片段文件
            with open(os.path.join(self.temp_dir, f"{self.filename}_chunk{i}"), 'wb') as f:
                f.write(b'chunk data')

    def test_get_dynamic_success(self):
        url = reverse('dynamic', kwargs={'user': self.user1.id, 'num': 1, 'from': 1, 'mup': 2})
        response = self.client.get(url)
        self.assertEqual(response.data['count'], 1)
        self.assertEqual(response.status_code, 200)

    def test_get_dynamic_fail(self):
        url = reverse('dynamic', kwargs={'user': self.user1.id, 'num': 1, 'from': 1, 'mup': 3})
        response = self.client.get(url)
        self.assertEqual(response.data['count'], 0)
        self.assertEqual(response.status_code, 200)

    def test_get_related_success(self):
        url = reverse('get_related', kwargs={'type': 'sports'})
        response = self.client.get(url)
        self.assertEqual(response.data[0]['type'], 'sports')
        self.assertEqual(response.status_code, 200)

    def test_get_related_fail(self):
        url = reverse('get_related', kwargs={'type': 'hooly'})
        response = self.client.get(url)
        self.assertEqual(len(response.data), 0)
        self.assertEqual(response.status_code, 200)

    def tearDown(self):
        # 删除测试文件夹和文件
        if os.path.exists(self.test_path):
            for file in os.listdir(self.test_path):
                os.remove(os.path.join(self.test_path, file))
            os.rmdir(self.test_path)
        if os.path.exists(self.temp_dir):
            for file in os.listdir(self.temp_dir):
                os.remove(os.path.join(self.temp_dir, file))
            os.rmdir(self.temp_dir)
        for i in range(3):
            chunk_path = os.path.join(self.temp_dir, f"{self.filename}_chunk{i}")
            if os.path.exists(chunk_path):
                os.remove(chunk_path)
        if os.path.exists(self.temp_dir):
            os.rmdir(self.temp_dir)

    def test_post_video_inspect_success(self):
        url = reverse('post_video_inspect')
        response = self.client.post(url, {'name': self.test_filename})
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data['index'], 3)

    def test_post_video_inspect_fail(self):
        url = reverse('post_video_inspect')
        response = self.client.post(url, {'name': 'nofilename'})
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data['index'], 0)

    def test_post_video_slice_success(self):
        url = reverse('post_video_slice')
        response = self.client.post(url, {
            'index': 1,
            'file': self.file,
            'filename': self.filename
        })
        self.assertEqual(response.status_code, 200)
        self.assertTrue(os.path.exists(f'{self.temp_dir}/{self.filename}_chunk1'))

    def test_post_video_slice_fail(self):
        url = reverse('post_video_slice')
        # 测试缺少文件名时的响应
        response = self.client.post(url, {
            'index': 1,
            'file': self.file
        })
        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.data['error'], 'Invalid request')

    @mock.patch('video.views.oss2.Bucket.put_object_from_file')
    @mock.patch('video.views.extract_first_frame')
    def test_post_video_merge_success(self, mock_extract_first_frame, mock_put_object_from_file):
        # 设置模拟返回值
        mock_extract_first_frame.return_value = 120  # 假设提取出的持续时间为120秒

        url = reverse('post_video_merge')  # 根据实际情况设置url name
        data = {
            'fileName': self.filename,
            'fileType': self.filetype,
            'title': self.title,
            'tags': self.tags,
            'user': self.user1.id,
            'type': self.video_type,
            'description': self.description,
        }
        response = self.client.post(url, data)

        # 检查响应
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data['message'], "Video chunks merged successfully")

        # 检查视频是否成功创建
        video = Videos.objects.latest('vid')  # 根据预期ID进行检查
        self.assertEqual(video.title, self.title)
        self.assertEqual(video.file_path, settings.OSS_READ_ROOT + f"/videos/{video.vid}.{self.filetype}")
        self.assertEqual(video.duration, 120)
        self.assertEqual(video.type, self.video_type)
        self.assertEqual(video.description, self.description)

        # 检查OSS上传是否被调用
        self.assertEqual(mock_put_object_from_file.call_count, 2)

        # 检查视频审核记录是否成功创建
        review = VideosReviewing.objects.get(video_id=video.vid)
        self.assertEqual(review.title, self.title)

        # 检查播放记录是否成功创建
        play = Play.objects.get(video_id=video.vid)
        self.assertEqual(play.user_id, 1)
        self.assertEqual(play.count, 0)
        self.assertEqual(play.progress, 0)

        video_output_path = os.path.join(settings.MEDIA_ROOT, 'videos', f"{video.vid}.{self.filetype}")
        cover_output_path = os.path.join(settings.MEDIA_ROOT, 'imgs/covers', f"{video.vid}.png")
        try:
            os.remove(cover_output_path)
        except FileNotFoundError:
            pass
        try:
            os.remove(video_output_path)
        except FileNotFoundError:
            pass

    def test_post_video_merge_fail(self):
        # 提交时缺少fileName字段
        url = reverse('post_video_merge')
        data = {
            # 'fileName': self.filename,  # 故意省略
            'fileType': self.filetype,
            'title': self.title,
            'tags': self.tags,
            'user': self.user1.id,
            'type': self.video_type,
            'description': self.description,
        }

        response = self.client.post(url, data)

        # 检查响应是否为400错误，表示请求有问题
        self.assertEqual(response.status_code, 400)

    def test_get_strange_success(self):
        url = reverse('get_strange', kwargs={'user': self.user3.id})
        response = self.client.get(url)
        result = response.data
        self.assertEqual(result[0]['vid'], '2')
        self.assertEqual(response.status_code, 200)

    def test_get_strange_fail(self):
        url = reverse('get_strange', kwargs={'user': self.user3.id})
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

    def test_get_profile_success(self):
        url = reverse('get_profile', kwargs={'mup': self.user2.id, 'num': 1, 'from': 0, 'type': 0})
        response = self.client.get(url)
        self.assertEqual(response.data['data'][0]['vid'], '1')
        self.assertEqual(response.status_code, 200)

    def test_get_profile_fail(self):
        url = reverse('get_profile', kwargs={'mup': self.user2.id, 'num': 1, 'from': 0, 'type': 1})
        response = self.client.get(url)
        self.assertEqual(response.data['count'], 0)
        self.assertEqual(response.status_code, 200)

    def test_get_column_favor_success(self):
        url = reverse('get_column_favor', kwargs={'coid': self.column_user5.coid, 'user': self.user4.id})
        response = self.client.get(url)
        self.assertEqual(response.data['all_favored'], True)

    def test_get_column_favor_fail(self):
        url = reverse('get_column_favor', kwargs={'coid': self.column2_user5.coid, 'user': self.user4.id})
        response = self.client.get(url)
        self.assertEqual(len(response.data['result']), 0)






